Skip to content

perf: cache parsed CREATE TABLE constraints in codegen (#643) - #649

Merged
iheitlager merged 2 commits into
mainfrom
perf/643-cache-ddl-constraints
Aug 29, 2026
Merged

perf: cache parsed CREATE TABLE constraints in codegen (#643)#649
iheitlager merged 2 commits into
mainfrom
perf/643-cache-ddl-constraints

Conversation

@iheitlager

Copy link
Copy Markdown
Member

Summary

  • compile_insert/compile_update_with_catalog both re-tokenized and re-parsed schema.sql on every call to recover CHECK/PRIMARY KEY/AUTOINCREMENT constraint info. Adds cached_create_table in src/codegen/stmt/insert.rs: a process-wide, content-addressed cache (OnceLock<Mutex<HashMap<String, Arc<CreateTable>>>>, same pattern as src/vfs/shm.rs's SHM_FILES), keyed by schema.sql, so the same DDL text is parsed once no matter how many statement compiles reuse it.
  • Design deviation from the ticket: the ticket proposed adding the cache as a field on TableSchema (src/schema/ddl_reader.rs). That's not possible — ddl_reader.rs must have zero dependency on src/parser (spec 002 Requirement 5, verified by its own scenario test). The cache instead lives at the codegen layer, where both TableSchema and parser types are already used.
  • Benchmark finding: insert_single/update_pk in tests/performance/crud.rs show no measurable change from this fix. Measured in isolation, parse_create_table costs ~5µs; those benchmarks run ~14ms/iteration dominated by fsync/journal/B-tree I/O, and bench_write compiles the program once outside its timed iter_batched loop anyway — so the reparse this ticket targets was never in that benchmark's hot path, and wouldn't be visible even if it were. The premise that this reparse was "a likely major contributor to a ~10x perf gap" doesn't hold up under measurement. The cache is still correct and useful for workloads that compile the same schema repeatedly (e.g. exec.rs's multi-statement script mode running many single-row INSERT/UPDATEs).

Refs: #643

Test plan

  • cargo test — full suite passes (959 lib tests + all integration suites, 0 failures)
  • cargo clippy --all-targets — clean
  • cargo fmt --check — clean
  • Measured parse_create_table cost in isolation (~5µs) vs. insert_single/update_pk bench iteration cost (~14ms) to verify/refute the ticket's perf premise before claiming a benchmark win

spend: matched estimate (small)

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

iheitlager and others added 2 commits August 29, 2026 20:39
Obligation ids in tests/mcdc/obligations.json are <file>_<line>; the
decisions at src/vdbe/exec.rs previously tagged exec_444/exec_664
drifted to exec_463/exec_647 as the file grew. Rename the existing
MC/DC vector tests to match so make test-mcdc discharges them again.

spend: trivial, matched estimate
…pile_update_with_catalog (#643)

compile_insert and compile_update_with_catalog both re-tokenized and
re-parsed schema.sql on every call purely to recover CHECK/PRIMARY
KEY/AUTOINCREMENT info. Add a process-wide, content-addressed cache
(cached_create_table, keyed by schema.sql) so the same DDL text is
only parsed once across however many statement compiles reuse it —
e.g. exec.rs's multi-statement script mode.

TableSchema itself can't carry this cache: src/schema/ddl_reader.rs
must have zero dependency on src/parser (spec 002 Requirement 5,
verified), so the cache lives in codegen instead, following the
existing OnceLock<Mutex<HashMap<...>>> pattern from src/vfs/shm.rs.

Note: insert_single/update_pk in tests/performance/crud.rs show no
measurable change from this — that benchmark compiles the program
once outside its timed loop, and even inline, parse_create_table
costs ~5µs against ~14ms/iter of I/O-dominated execution time. The
premise that this reparse was a major contributor to the oracle perf
gap doesn't hold up under measurement; the cache is still correct and
useful for workloads that compile the same schema repeatedly.

spend: matched estimate (small)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@iheitlager
iheitlager merged commit 9c456d4 into main Aug 29, 2026
6 checks passed
@iheitlager
iheitlager deleted the perf/643-cache-ddl-constraints branch August 29, 2026 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant